# coding=utf-8

import traceback
from flask import request, session, current_app, redirect, url_for, jsonify
from sqlalchemy.exc import SQLAlchemyError
from sqlite3 import Error
from urllib.parse import urlparse, urljoin
import pprint
from random import randint


def save_request_session_info():
    request_session_dict = request.__dict__
    request_session_dict.update(dict(session=session))
    current_app.logger.error(pprint.pformat(request_session_dict))


def is_safe_url(target):
    """判断url是否属于程序内部"""
    ref_url = urlparse(request.host_url)
    test_url = urlparse(urljoin(request.host_url, target))
    return test_url.scheme in ('http', 'https') and \
           ref_url.netloc == test_url.netloc


def create_hash(length):
    """生成指定长度随机hash数值"""
    l = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', \
         'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
    return ''.join([l[randint(0, len(l) - 1)] for _ in range(length)])


def exception_handle(app, exc):
    app.logger.error(traceback.format_exc())
    tbexc = traceback.TracebackException.from_exception(exc)
    if issubclass(tbexc.exc_type, (Error, SQLAlchemyError)):
        from app.extensions import db
        db.session.rollback()
    save_request_session_info()


def redirect_back(default='main.index', **kwargs):
    for target in request.args.get('next'), request.referrer:
        if not target:
            continue
        if is_safe_url(target):
            return redirect(target)
    return redirect(url_for(default, **kwargs))


def get_form_from_request(req, name):
    """
    从request.form中获取参数name的值，如果不存在则返回错误
    :param req: flask.request
    :param name: 参数名
    :return: 0,报错返回
             1,取到指定参数值
    """
    value = req.form.get(name, None)
    if value is None:
        return 0, jsonify({
            'error_no': -1,
            'error_msg': '缺少参数%s' % name,
        })
    else:
        return 1, value


def get_project_id_from_current_element(element):
    from app.models import Case, LogicController, Tool

    if isinstance(element, Case):
        return element.scene.module.project_id
    elif isinstance(element, LogicController):
        return LogicController.get_project_id_from_current_logic_controller(logic_controller=element)
    elif isinstance(element, Tool):
        return Tool.get_project_id_from_current_tool(tool=element)
